using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework.Content.Pipeline;
using Microsoft.Xna.Framework.Content.Pipeline.Graphics;
using Drawing = System.Drawing;
using Imaging = System.Drawing.Imaging;
using Scurvy.Media.Avi;
using System.Runtime.InteropServices;

namespace Scurvy.Media.Pipeline
{
    /// <summary>
    /// Allows you to import a video and translate it to a series of textures using the GDI+ API
    /// </summary>
    /// <typeparam name="T">a struct that dictates the pixel depth</typeparam>
    public abstract class VideoImporter<T> : ContentImporter<VideoContent> where T : struct, IEquatable<T>
    {
        public override VideoContent Import(string filename, ContentImporterContext context)
        {
            Initialize(filename);
            int count = this.NumberOfFrames;
            
            //get "video content type" from subclass

            //return "video content type"

            VideoContent vid = new VideoContent(count, this.FrameRate);
            for (int i = 0; i < count; i++)
            {
                using (Drawing.Bitmap bitmap = GetFrame(i))
                {
                    Texture2DContent c = TranslateBitmap(bitmap);
                    vid.Add(c);
                }
            }
            return vid;
        }

        #region Abstract Methods and Properties

        protected abstract int NumberOfFrames { get;}
        protected abstract double FrameRate { get;}
        protected abstract void Initialize(string filename);
        protected abstract System.Drawing.Bitmap GetFrame(int i);

        #endregion

        #region Private Methods

        private Texture2DContent TranslateBitmap(System.Drawing.Bitmap bitmap) 
        {
            Texture2DContent c = new Texture2DContent();
            BitmapContent b = new PixelBitmapContent<T>(bitmap.Width, bitmap.Height);
            c.Faces[0].Add(b);
            
            GetData(bitmap);
            b.SetPixelData(pixelBuffer);
            //c.ConvertBitmapType(typeof(Dxt1BitmapContent));
            return c;
        }

        #endregion

        #region Public Methods
        byte[] pixelBuffer;

        public void GetData(Drawing.Bitmap bmp)
        {
            // Lock the bitmap's bits.
            Drawing.Rectangle rect = new Drawing.Rectangle(0, 0, bmp.Width, bmp.Height);
            Imaging.BitmapData bmpData =
            bmp.LockBits(rect, Imaging.ImageLockMode.ReadOnly,
                         bmp.PixelFormat);

            // Get the address of the first line.
            IntPtr ptr = bmpData.Scan0;

            // Declare an array to hold the bytes of the bitmap.
            int numBytes = bmp.Width * bmp.Height *2;
            if (pixelBuffer == null)
            {
                pixelBuffer = new byte[numBytes];
            }

            // Copy the RGB values into the array.
            Marshal.Copy(ptr, pixelBuffer, 0, numBytes);
        }
        #endregion
    }
}
 